import Vue from 'vue'

! function (factory) {
    if (typeof require === 'function' && typeof exports === 'object' && typeof module === 'object') {
        var target = module['exports'] || exports;
        factory(target);
    } else if (typeof define === 'function' && define['amd']) {
        define(['exports'], factory);
    } else {
        factory(window['kt'] = {});
    }
}(function (utExports) {
    'use strict';

    var kt = typeof utExports !== 'undefined' ? utExports : {};

    /**
     * 获取网站的根地址
     */
    kt.getBaseUrl = function () {
        if (process.env.NODE_ENV === 'production') {
            return "";
        }

        var baseUrl = localStorage.serverAddress;
        if (!baseUrl.endWith("/")) {
            baseUrl += "/";
        }

        return baseUrl;
    }

    /**
     * 通过Get方法调用WebAPI
     * @param {string} apiUrl WebAPI的URL地址
     * @param {*} params 传递的参数
     * @returns {string} response结果
     */
    kt.get = function (apiUrl, params) {
        var queryString = null;
        if (!this.isNull(params)) {
            for (var key in params) {
                queryString += '&' + key + '=' + encodeURIComponent(params[key]);
            }

            queryString = queryString.substr(1);
        }

        if (!this.isNullOrWhiteSpace(queryString)) {
            apiUrl += "?" + queryString;
        }
        return Vue.http.get(apiUrl)
            .then(function (response) {
                if (response.data != null && response.data.ErrorCode != null) {
                    if (response.data.ErrorCode !== 0) {
                        return Promise.reject(response.data.Message);
                    } else {
                        return response.data.Data;
                    }
                }
                return response.data;
            }, function (errorResponse) {
                if (errorResponse.status === 401) {
                    alert("您没有权限访问该资源.");
                    return;
                }
                return Promise.reject(errorResponse.statusText);
            });
    };

    /**
     * 通过post的方法调用WebAPI
     * @param {string} apiUrl WebAPI的URL地址
     * @param {*} para 要post到服务器端的数据
     * @returns {string} response结果
     */
    kt.post = function (apiUrl, data, params) {
        return Vue.http.post(apiUrl, data, params)
            .then(function (response) {
                if (response.data != null && response.data.ErrorCode != null) {
                    if (response.data.ErrorCode !== 0) {
                        return Promise.reject(response.data.Message);
                    } else {
                        return response.data.Data;
                    }
                }
                return response.data;
            }, function (errorResponse) {
                if (errorResponse.status === 401) {
                    alert("您没有权限访问该资源.");
                    return;
                }
                return Promise.reject(errorResponse.statusText);
            });
    };

    var loadingInstance; //loading实例
    /**
     * 打开lookup
     * @param {string} url lookuppage url
     */
    kt.sLookup = function (url) {
        var l = (screen.availWidth - 560) / 2;
        var t = (screen.availHeight - 614) / 2;

        window.open(url, "_blank", "width=560,height=614,top=" + t + ",left=" + l + ",toolbar=no,menubar=no, scrollbars=no, resizable=no, location=no, status=no");
    }

    /**
     * 打开单据编辑界面
     * @param {string} url lookuppage url
     */
    kt.editWindow = function (url) {
        var l = (screen.availWidth - 1440) / 2;
        var t = (screen.availHeight - 900) / 2;

        window.open(url, "_blank", "width=1440,height=900,top=" + t + ",left=" + l + ",toolbar=no,menubar=no, scrollbars=no, resizable=no, location=no, status=no");
    }

    /**
     * showAlertDialog的简化写法，按钮的显示文字固定为“确定”。
     * @param {String} content 消息提示的正文
     */
    kt.alert = function (content, callback) {
        kt.showAlertDialog('提示', content, {
            callback: callback
        });
    };

    /**
     * 弹出提示对话框，可以自定义按钮的显示文字；返回Promise对象。
     * @param  {string} title                提示标题
     * @param  {string} content              提示正文
     * @param  {string} options
     */
    kt.showAlertDialog = function (title, content, options) {
        return Vue.prototype.$alert(content, title, options)
    }

    /**
     * showConfirmDialog简化写法，按钮的显示文字固定为“确定”和“取消”。
     * @param  {string} content 消息提示正文
     * @return {Promise}         在then和catch中执行确定和取消的操作
     */
    kt.confirm = function (content) {
        return kt.showConfirmDialog('', content, '确定', '取消', 'info')
    }

    /**
     * 弹出confirm
     * @param  {string} title                消息提示标题
     * @param  {string} content              消息提示正文
     * @param  {sting} confirmButtonContent  确定按钮文字
     * @param  {string} CancelButtonContent  取消按钮文字
     * @param  {sting} confirmType           提示类型
     * @return {Promise}
     */
    kt.showConfirmDialog = function (title, content, confirmButtonContent, CancelButtonContent, confirmType) {
        if (!kt.isString(title)) {
            throw new Error('kt.showConfirmDialog title parameter must be string.');
        }
        if (!kt.isString(content)) {
            throw new Error('kt.showConfirmDialog content parameter must be string.');
        }
        if (!kt.isString(confirmButtonContent)) {
            throw new Error('kt.showConfirmDialog confirmButtonContent parameter must be string.');
        }
        if (!kt.isString(CancelButtonContent)) {
            throw new Error('kt.showConfirmDialog CancelButtonContent parameter must be string.');
        }
        return Vue.prototype.$confirm(content, title, {
            confirmButtonText: confirmButtonContent,
            CancelButtonText: CancelButtonContent,
            type: confirmType
        })
    }

    /**
     * 打开loading提示
     * @param  {string} content 等待提示内容
     * @param  {obje} dom       加载dom对象，不传对象则全屏
     */
    kt.showLoadingToast = function (content, dom) {
        if (!kt.isNull(loadingInstance)) {
            return;
        }
        let options = {};
        if (!kt.isNull(content)) {
            options.text = content
        }
        if (!kt.isNull(dom)) {
            options.target = dom
        }
        loadingInstance = Vue.prototype.$loading(options)
    }

    /**
     * 关闭loading
     */
    kt.hideLoadingToast = function () {
        if (kt.isNull(loadingInstance)) {
            return;
        }
        loadingInstance.close();
        loadingInstance = null;
    }

    /**
     * 弹出错误文字提示
     * @param  {string}  content 提示内容
     * @param  {Boolean} isClose 是否可手动关闭
     */
    kt.showErrorToast = function (content, isClose) {
        Vue.prototype.$message({
            showClose: isClose,
            message: content,
            type: 'error'
        });
    };

    /**
     * 弹出成功的文字提示
     * @param  {string}  content 提示内容
     * @param  {Boolean} isClose 是否可手动关闭
     */
    kt.showSuccessToast = function (content, isClose) {
        Vue.prototype.$message({
            showClose: isClose,
            message: content,
            type: 'success'
        });
    };

    /**
     * 刷新页面
     */
    kt.refresh = function () {
        Vue.router.go(0)
    }

    /**
     * 判断一个字符串是否包含某字符串
     * @param substr 包含的字符串
     * @param ignoreCase 是否忽略大小写
     * @returns {boolean} 如果包含，则返回true，否则返回 false
     */
    String.prototype.contains = function (substr, ignoreCase) {
        if (ignoreCase === null || ignoreCase === undefined) {
            ignoreCase = false;
        }

        if (ignoreCase) {
            return this.search(new RegExp(substr, "i")) > -1;
        } else {
            return this.search(substr) > -1;
        }
    };

    /**
     * 判断一个字符串是不是以某字符串结尾
     * @param s
     * @returns {boolean} 如果是，则返回true，否则返回 false
     */
    String.prototype.endWith = function (s, ignoreCase) {
        if (s === null || s === "" || this.length === 0 || s.length > this.length) {
            return false;
        }
        var ns = this.substring(this.length - s.length);
        if (ignoreCase) {
            return ns.toLowerCase() === s.toLowerCase();
        } else {
            return ns === s;
        }
    };

    /**
     * 字符格式化，同C# String.Format方法
     */
    String.prototype.format = function () {
        var content = this;
        for (var i = 0; i < arguments.length; i++) {
            var replacement = '{' + i + '}';
            content = content.replace(replacement, arguments[i]);
        }
        return content;
    };

    /**
     * 判断一个字符串是不是以某字符串开头
     * @param s
     * @returns {boolean} 如果是，则返回true，否则返回 false
     */
    String.prototype.startWith = function (s, ignoreCase) {
        if (s === null || s === "" || this.length === 0 || s.length > this.length) {
            return false;
        }
        var ns = this.substr(0, s.length);
        if (ignoreCase) {
            return ns.toLowerCase() === s.toLowerCase();
        } else {
            return ns === s;
        }
    };

    /**
     * 移除字符串前后的空格或其它特殊字符，同C#中的Trim方法。
     */
    String.prototype.trim = function (trimChars) {
        var result = this;

        if (typeof trimChars !== "string" || trimChars.length <= 0) {
            trimChars = " ";
        }

        var count = result.length;

        while (count > 0) { //trim the head position
            if (trimChars.indexOf(result[0]) >= 0) {
                result = result.substring(1);
                count--;
            } else {
                break;
            }
        }
        while (count > 0) { //trim the tail position
            if (trimChars.indexOf(result[count - 1]) >= 0) {
                result = result.substring(0, count - 1);
                count--;
            } else {
                break;
            }
        }
        return result;
    };

    /**
     * 日期格式化
     * @param  {date} date   待格式化日期
     * @param  {string} mask 格式
     * @param  {[type]} utc  [description]
     * @return {string}      格式化后的日期字符串
     */
    kt.formatDateTime = function (date, mask, utc) {

        var token = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g,
            timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\d{4})?)\b/g,
            timezoneClip = /[^-+\dA-Z]/g,
            pad = function (val, len) {
                val = String(val);
                len = len || 2;
                while (val.length < len)
                    val = "0" + val;
                return val;
            };

        var dateFormat = {
            masks: {},
            i18n: {}
        };

        // Some common format strings
        dateFormat.masks = {
            "default": "ddd mmm dd yyyy HH:MM:ss",
            shortDate: "m/d/yy",
            mediumDate: "mmm d, yyyy",
            longDate: "mmmm d, yyyy",
            fullDate: "dddd, mmmm d, yyyy",
            shortTime: "h:MM TT",
            mediumTime: "h:MM:ss TT",
            longTime: "h:MM:ss TT Z",
            isoDate: "yyyy-mm-dd",
            isoTime: "HH:MM:ss",
            isoDateTime: "yyyy-mm-dd'T'HH:MM:ss",
            isoUtcDateTime: "UTC:yyyy-mm-dd'T'HH:MM:ss'Z'"
        };

        // Internationalization strings
        dateFormat.i18n = {
            dayNames: [
                "Sun",
                "Mon",
                "Tue",
                "Wed",
                "Thu",
                "Fri",
                "Sat",
                "Sunday",
                "Monday",
                "Tuesday",
                "Wednesday",
                "Thursday",
                "Friday",
                "Saturday"
            ],
            monthNames: [
                "Jan",
                "Feb",
                "Mar",
                "Apr",
                "May",
                "Jun",
                "Jul",
                "Aug",
                "Sep",
                "Oct",
                "Nov",
                "Dec",
                "January",
                "February",
                "March",
                "April",
                "May",
                "June",
                "July",
                "August",
                "September",
                "October",
                "November",
                "December"
            ]
        };

        // Regexes and supporting functions are cached through closure
        return function (date, mask, utc) {
            var dF = dateFormat;

            // You can't provide utc if you skip other args (use the "UTC:" mask prefix)
            if (arguments.length === 1 && Object.prototype.toString.call(date) === "[object String]" && !/\d/.test(date)) {
                mask = date;
                date = undefined;
            }

            // Passing date through Date applies Date.parse, if necessary
            date = date ?
                new Date(date) :
                new Date();
            if (isNaN(date))
                throw SyntaxError("invalid date");

            mask = String(dF.masks[mask] || mask || dF.masks["default"]);

            // Allow setting the utc argument via the mask
            if (mask.slice(0, 4) == "UTC:") {
                mask = mask.slice(4);
                utc = true;
            }

            var _ = utc ?
                "getUTC" :
                "get",
                d = date[_ + "Date"](),
                D = date[_ + "Day"](),
                m = date[_ + "Month"](),
                y = date[_ + "FullYear"](),
                H = date[_ + "Hours"](),
                M = date[_ + "Minutes"](),
                s = date[_ + "Seconds"](),
                L = date[_ + "Milliseconds"](),
                o = utc ?
                    0 :
                    date.getTimezoneOffset(),
                flags = {
                    d: d,
                    dd: pad(d),
                    ddd: dF.i18n.dayNames[D],
                    dddd: dF.i18n.dayNames[D + 7],
                    m: m + 1,
                    mm: pad(m + 1),
                    mmm: dF.i18n.monthNames[m],
                    mmmm: dF.i18n.monthNames[m + 12],
                    yy: String(y).slice(2),
                    yyyy: y,
                    h: H % 12 || 12,
                    hh: pad(H % 12 || 12),
                    H: H,
                    HH: pad(H),
                    M: M,
                    MM: pad(M),
                    s: s,
                    ss: pad(s),
                    l: pad(L, 3),
                    L: pad(L > 99 ?
                        Math.round(L / 10) :
                        L),
                    t: H < 12 ?
                        "a" :
                        "p",
                    tt: H < 12 ?
                        "am" :
                        "pm",
                    T: H < 12 ?
                        "A" :
                        "P",
                    TT: H < 12 ?
                        "AM" :
                        "PM",
                    Z: utc ?
                        "UTC" :
                        (String(date).match(timezone) || [""])
                            .pop()
                            .replace(timezoneClip, ""),
                    o: (o > 0 ?
                        "-" :
                        "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),
                    S: ["th", "st", "nd", "rd"][d % 10 > 3 ?
                        0 :
                        (d % 100 - d % 10 != 10) * d % 10
                    ]
                };

            return mask.replace(token, function ($0) {
                return $0 in flags ?
                    flags[$0] :
                    $0.slice(1, $0.length - 1);
            });
        };
    }();

    /**
     * 判断字符是否有效的手机号码
     * @returns {boolean}
     */
    kt.isCellphone = function (str) {
        var regex = /^1[3|4|5|6|7|8|9][0-9]{9}$/;
        return regex.test(str);
    };

    /**
     * 判断是否是日期类型
     * @param d
     * @returns {boolean}
     */
    kt.isDate = function (d) {
        if (kt.isNull(d)) {
            return false;
        }

        return d instanceof Date && !isNaN(d.valueOf());
    };

    /**
     * 检查是否是邮件地址
     */
    kt.isEmailAddress = function (str) {
        var regex = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/;

        return regex.test(str);
    };

    /**
     * 判断字符是否有效的身份证号码
     * @returns {boolean}
     */
    kt.isIDCard = function (str) {
        var regex = /^\d{6}(18|19|20)?\d{2}(0[1-9]|1[12])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/;
        return regex.test(str);
    };

    /**
     * 检查是否为整数
     * @param  {string}  str 数字
     * @return {Boolean}            若为整数，返回TRUE；否则，返回false
     */
    kt.isInteger = function (str) {
        var regex = /^[-]{0,1}[0-9]{1,}$/;
        return regex.test(str);
    };

    /**
     * 判断一个变量是否是undefined或者null
     * @param o 需要进行判断的变量
     * @returns {boolean} 如果是undified或者null，则返回true，否则返回 false
     */
    kt.isNull = function (o) {
        return o === undefined || o === null;
    };

    /**
     * 判断一个字符串是否是undified、null、“”
     * @param s 字符串变量
     * @returns {boolean} 如果是，则返回true，否则返回false
     */
    kt.isNullOrWhiteSpace = function (s) {
        return this.isNull(s) || s.trim() === "";
    };

    /**
     * 检查是否为数字（实数）
     * @param  {string}  str 待检查的数字
     * @return {Boolean}           若为数字，返回true；否则返回false
     */
    kt.isNumeric = function (str) {

        var regex = /^(-|\+)?\d+(\.\d+)?$/;

        return regex.test(str);
    };

    /**
     * 检查是否是手机号码或者电话号码
     */
    kt.isPhone = function (str) {
        return this.isCellphone(str) || this.isTelephone(str);
    };

    /**
     * 不区分大小写、{}，比较两个guid
     * @param  {String}  guid1 参与比较的第一个Guid
     * @param  {String}  guid2 参与比较的第二个Guid
     * @return {Boolean}
     */
    kt.isSameGuid = function (guid1, guid2) {

        var isEqual;
        if (guid1 === null || guid2 === null) {
            isEqual = false;
        } else {
            isEqual = guid1
                .replace(/[{}]/g, "")
                .toLowerCase() === guid2
                    .replace(/[{}]/g, "")
                    .toLowerCase();
        }

        return isEqual;
    };

    /**
     * 判断js变量是否为string类型
     * @param  {object}  obj 要判断的Js对象
     * @return {Boolean}
     */
    kt.isString = function (obj) {
        return typeof obj === "string";
    };

    /**
     * 判断字符是否有效的电话号码
     * @returns {boolean}
     */
    kt.isTelephone = function (str) {
        var reg = /^\d{3,4}-\d{7,8}(-\d{3,4})?$/;
        return reg.test(str);
    };

    /**
     * 检查是否为正整数
     * @param  {string}  str 数字字符串
     * @return {Boolean}            若为正整数，返回TRUE；否则，返回false
     */
    kt.isUnsignedInteger = function (str) {
        var regex = /^[1]{0,1}[0-9]{1,}$/;

        return regex.test(str);
    };

    /**
     * 检查是否为正数
     * @param  {string}  str 数字
     * @return {Boolean}           若为正数，返回TRUE；否则返回false
     */
    kt.isUnsignedNumeric = function (str) {
        var regex = /^\d+(\.\d+)?$/;

        return regex.test(str);
    };

    /**
     * 生成一个新的GUID
     * @returns {string} GUID
     */
    kt.newGuid = function () {
        function s4() {
            return Math.floor((1 + Math.random()) * 0x10000)
                .toString(16)
                .substring(1);
        }
        return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
    };

    /**
     * 同步POST执行后台方法
     * @param  {String} url URL地址
     * @param  {String} data   传递参数
     * @return {[type]}           [description]
     */
    kt.postResponse = function (url, data) {
        var xmlhttp = this.getXHR();
        xmlhttp.open("post", url, false);
        xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xmlhttp.send(data);

        return xmlhttp.responseText;
    };
});
